package me.chyxion.spring.ext;

import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;

/**
 * @version 0.0.3
 * @since 0.0.1
 * @author Shaun Chyxion <br />
 * chyxion@163.com <br />
 * Sep 21, 2014 8:32:06 PM
 */
public class DataModel {
	private boolean success = true;
	private boolean raw = false;
	/**
	 * error code
	 */
	private Object code = 0;
	private Object message;
	private Object data;

	/**
	 * @since 0.0.3
	 */
	private Throwable exception;

	/**
	 * @since 0.0.3
	 */
    public DataModel() {
    }

	/**
	 * @param data
	 */
    public DataModel(Object data) {
	    this.data = data;
    }

	/**
	 * @since 0.0.3
	 * @param exception
	 */
    public DataModel(Throwable exception) {
    	this.exception = exception;
    }

	/**
	 * @return the success
	 */
	public boolean isSuccess() {
		return success;
	}

	/**
	 * @param success the success to set
	 * @return 
	 */
	public DataModel setSuccess(boolean success) {
		this.success = success;
		return this;
	}

	/**
	 * @return the code
	 */
	public Object getCode() {
		return code;
	}

	/**
	 * @param code the code to set
	 * @return 
	 */
	public DataModel setCode(Object code) {
		this.code = code;
		return this;
	}

	/**
	 * @return the message
	 */
	public Object getMessage() {
		return message;
	}

	/**
	 * @param message the message to set
	 * @return 
	 */
	public DataModel setMessage(Object message) {
		this.message = message;
		return this;
	}

	/**
	 * @return the data
	 */
	public Object getData() {
		return data;
	}

	/**
	 * @param data the data to set
	 */
	public void setData(Object data) {
		this.data = data;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
    @Override
    public String toString() {
        return JSON.toJSONString(formattedData());
    }

    /**
     * return formatted data
     * @return
     */
    public Object formattedData() {
    	Object dataRtn = null;
    	if (raw) {
    		dataRtn = data;
    	}
    	else {
			Map<String, Object> mapData = new HashMap<String, Object>();
			mapData.put("success", success);
			mapData.put("data", data);
			if (!success) {
				Map<String, Object> mapStatus = new HashMap<String, Object>();
				mapStatus.put("code", code);
				mapStatus.put("message", message != null ? message : 
					exception != null ? exception.getMessage() : null);
				mapData.put("status", mapStatus);
			}
			dataRtn = mapData;
    	}
    	return dataRtn;
    }

	/**
	 * @return the raw
	 */
	public boolean isRaw() {
		return raw;
	}

	/**
	 * @param raw the raw to set
	 * @return 
	 */
	public DataModel setRaw(boolean raw) {
		this.raw = raw;
		return this;
	}

	/**
	 * @return the exception
	 */
	public Throwable getException() {
		return exception;
	}

	/**
	 * @param exception the exception to set
	 */
	public void setException(Throwable exception) {
		this.exception = exception;
	}
}
